package sg.edu.nus.iss.jass.gui;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;

import sg.edu.nus.iss.jass.constant.CommonConstants;
import sg.edu.nus.iss.jass.controller.JobSearchController;
import sg.edu.nus.iss.jass.controller.MainController;
import sg.edu.nus.iss.jass.dto.Company;
import sg.edu.nus.iss.jass.dto.GeographicalLocation;
import sg.edu.nus.iss.jass.dto.SearchCriteria;
import sg.edu.nus.iss.jass.dto.SkillReference;
import sg.edu.nus.iss.jass.exception.ValidationException;
import sg.edu.nus.iss.jass.gui.component.ValidateJTextField;
import sg.edu.nus.iss.jass.util.Util;
import sg.edu.nus.iss.jass.validation.ValidationRule;

public class SearchJobPanel extends JPanel {

	private JobSearchFormPanel parent;
	private JobSearchController jobSearchController;
	private List<SkillReference> skills;
	private List<Company> companies;
	private List<GeographicalLocation> locations;

	// Control List for SearchJobPanel
	private JLabel jLabel5;
	private JLabel jLabel7;
	private ValidateJTextField noOfDaysTxt;
	private JLabel jLabel6;
	private JComboBox salaryRangeCbx;
	private JLabel jLabel1;
	private JButton searchBtn;
	private JButton resetBtn;
	private JList skillList;
	private JComboBox companyCbx;
	private JComboBox jobLocCbx;
	private JLabel jLabel4;
	private JLabel jLabel3;
	private ValidateJTextField jobDescTxt;
	private JLabel jLabel2;

	public SearchJobPanel(JobSearchFormPanel parent) {
		super();
		this.parent = parent;
		this.jobSearchController = MainController.getInstance().getJobSearchController();
		this.createSearchPanel();
	}

	private void createSearchPanel() {
		try {
			this.setLayout(null);
			this.setPreferredSize(new java.awt.Dimension(650, 175));
			{
				jLabel2 = new JLabel();
				this.add(jLabel2);
				jLabel2.setText("Job Description");
				jLabel2.setLayout(null);
				jLabel2.setBounds(21, 15, 91, 14);
			}
			{
				jobDescTxt = new ValidateJTextField("Job Description");
				this.add(jobDescTxt);
				jobDescTxt.setBounds(130, 12, 180, 21);
			}
			{
				jLabel3 = new JLabel();
				this.add(jLabel3);
				jLabel3.setText("Company");
				jLabel3.setLayout(null);
				jLabel3.setBounds(21, 68, 97, 14);
			}
			{
				jLabel4 = new JLabel();
				this.add(jLabel4);
				jLabel4.setText("Job Location");
				jLabel4.setLayout(null);
				jLabel4.setBounds(21, 42, 91, 14);
			}
			{
				jLabel5 = new JLabel();
				this.add(jLabel5);
				jLabel5.setText("Skill");
				jLabel5.setLayout(null);
				jLabel5.setBounds(340, 13, 35, 14);
			}
			{
				jobLocCbx = new JComboBox();
				this.add(jobLocCbx);
				jobLocCbx.setBounds(130, 39, 180, 21);
			}
			{
				companyCbx = new JComboBox();
				this.add(companyCbx);
				companyCbx.setBounds(130, 65, 180, 21);
			}
			{
				
				skillList = new JList();
				JScrollPane listPane = new JScrollPane(skillList);
				listPane.setBounds(400, 12, 188, 98);
				skillList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
				skillList.setLayout(null);
				skillList.setVisibleRowCount(-1);
				skillList.setBounds(400, 12, 188, 98);
				this.add(listPane);
			}
			{
				jLabel1 = new JLabel();
				this.add(jLabel1);
				jLabel1.setText("Salary Range");
				jLabel1.setBounds(21, 94, 80, 16);
			}
			{
				salaryRangeCbx = new JComboBox();
				this.add(salaryRangeCbx);
				salaryRangeCbx.setBounds(130, 91, 180, 23);
			}
			{
				jLabel6 = new JLabel();
				this.add(jLabel6);
				jLabel6.setText("Within");
				jLabel6.setBounds(21, 122, 91, 16);
			}
			{
				noOfDaysTxt = new ValidateJTextField("Search No of Days", ValidationRule.NUMERIC);
				this.add(noOfDaysTxt);
				noOfDaysTxt.setBounds(130, 119, 62, 23);
			}
			{
				jLabel7 = new JLabel();
				this.add(jLabel7);
				jLabel7.setText("days");
				jLabel7.setBounds(200, 122, 35, 16);
			}
			{
				searchBtn = new JButton();
				this.add(searchBtn);
				searchBtn.setLayout(null);
				searchBtn.setText("Search");
				searchBtn.setBounds(505, 126, 80, 21);
				searchBtn.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent evt) {
						parent.clearSearchResult();
						parent.clearMsg();
						try {
							jobSearchController.processSearch(getSearchCriteria());
						} catch (Exception e) {
							parent.showMsg(e.getMessage(), false);
							e.printStackTrace();
						}
					}
				});
			}
			{
				resetBtn = new JButton();
				this.add(resetBtn);
				resetBtn.setLayout(null);
				resetBtn.setText("Reset");
				resetBtn.setBounds(400, 126, 80, 21);
				resetBtn.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent evt) {
						resetSearchCriteria();
					}
				});
			}

			this.linkSkill();
			this.linkCompany();
			this.linkLocation();
			this.linkSalaryRange();
			this.setSize(600, 200);
		} catch (Exception e) {
			// add your error handling code here
			e.printStackTrace();
		}
	}
	
	private void resetSearchCriteria(){
		this.jobDescTxt.clearText();
		this.noOfDaysTxt.clearText();
		this.jobLocCbx.setSelectedIndex(0);
		this.companyCbx.setSelectedIndex(0);
		this.salaryRangeCbx.setSelectedIndex(0);
		this.skillList.clearSelection();
	}

	private void linkSkill() {

		skills = jobSearchController.getAllSkills();
		if (Util.isEmpty(skills)) {
			return;
		}
		String[] skillNames = new String[skills.size()];
		
		for (int i = 0; i < skills.size(); i++) {
			skillNames[i] = skills.get(i).getName();
		}
		ListModel skillListModel = new DefaultComboBoxModel(skillNames);
		this.skillList.setModel(skillListModel);

	}

	private void linkCompany() {

		companies = jobSearchController.getAllCompanies();
		if (Util.isEmpty(companies)) {
			return;
		}
		String[] names = new String[companies.size()];
		
		for (int i = 0; i < companies.size(); i++) {
			names[i] = companies.get(i).getName();
		}
		ComboBoxModel cbxModel = new DefaultComboBoxModel(names);
		this.companyCbx.setModel(cbxModel);

		this.companyCbx.insertItemAt("--Select Company--", 0);
		this.companyCbx.setSelectedIndex(0);
	}

	private void linkLocation() {

		locations = jobSearchController.getAllLocations();
		if (Util.isEmpty(locations)) {
			return;
		}
		String[] names = new String[locations.size()];

		for (int i = 0; i < locations.size(); i++) {
			names[i] = locations.get(i).getCountry();
		}
		ComboBoxModel cbxModel = new DefaultComboBoxModel(names);
		this.jobLocCbx.setModel(cbxModel);
		
		this.jobLocCbx.insertItemAt("--Select Location--", 0);
		this.jobLocCbx.setSelectedIndex(0);
	}

	private void linkSalaryRange() {
		
		ComboBoxModel cbxModel = new DefaultComboBoxModel(
				CommonConstants.salaryRanges.toArray(new String[0]));
		
		this.salaryRangeCbx.setModel(cbxModel);
		
		this.salaryRangeCbx.insertItemAt("--Select Salary Range--", 0);
		this.salaryRangeCbx.setSelectedIndex(0);
	}

	private SearchCriteria getSearchCriteria() throws Exception {
		SearchCriteria searchCriteria = new SearchCriteria();
		
		if(this.companyCbx.getSelectedIndex()>0)
			searchCriteria.setCompanyId(this.companies.get(
					this.companyCbx.getSelectedIndex()-1).getId());
		
		try {
			searchCriteria.setKeyword(this.jobDescTxt.getValidatedText());
		} catch (ValidationException e) {
			e.printStackTrace();
		}
		if(this.jobLocCbx.getSelectedIndex()>0)
			searchCriteria.setLocationId(this.locations.get(
					this.jobLocCbx.getSelectedIndex()-1).getId());
		
		if(this.salaryRangeCbx.getSelectedIndex()>0)
			searchCriteria.setSalaryRange(this.salaryRangeCbx.getSelectedItem()
					.toString());
		
		try {
			searchCriteria.setNoOfDays(this.noOfDaysTxt.getValidatedText());
		} catch (ValidationException e) {e.printStackTrace();
			throw e;
		}
		
		ArrayList<String> skillIds = new ArrayList<String>();
		int[] indexes = skillList.getSelectedIndices();
		for (int i = 0; i < indexes.length; i++)
			skillIds.add(skills.get(indexes[i]).getId());
		searchCriteria.setSkillIds(skillIds);

		return searchCriteria;
	}
}
